INITSEG     equ 0x9000
SYSSEG      equ 0x1000
SETUPSEG    equ 0x9020

start:
    mov ax, INITSEG
    mov ds, ax

    mov ah, 0x88
    int 0x15            ; 获取扩展内存大小
    mov [2], ax

    mov ah, 0x12
    mov bl, 0x10
    int 0x10            ; 获取EGA信息
    mov [8], ax         ; ??
    mov [10], bx        ; 显示内存、显示状态
    mov [12], cx        ; 特性参数

    mov ax, 0x19
    mov [14], al        ; 行数

    mov ah, 0x03
    xor bh, bh
    int 0x10
    mov [0], dx         ; 读取光标位置

    mov ah, 0x0f
    int 0x10
    mov [4], bx         ; 显示页面
    mov [6], ax         ; 显示模式、字符列数

    cli                 ; 保护模式下中断机制尚未建立，应禁止中断
    mov ax, 0
    mov bx, 0x1000
    cld
do_move:                ; 将内核从0x10000移动到0
    mov es, ax
    add ax, 0x100
    cmp ax, INITSEG
    jz  end_move
    mov ds, bx
    add bx, 0x100
    sub di, di
    sub si, si
    mov cx, 0x800
    rep
    movsw               ; 每次移动4KB数据
    jmp do_move

end_move:
    mov ax, SETUPSEG
    mov ds, ax
    lgdt    [gdt_48]    ; 初始化GDT描述符，加载gdtr

    mov al, 2
    out 0x92, al        ; 打开A20地址线

    mov ax, 0x0001
    lmsw    ax          ; 设置cr0寄存器的PE位为1
    jmp 0x10:0          ; 跳转到0地址

gdt:
    dw  0, 0, 0, 0      ; dummy
    dw  0, 0, 0, 0      ; unused
    dw  0x07ff, 0x0000, 0x9a00, 0x00c0
    dw  0x07ff, 0x0000, 0x9200, 0x00c0

gdt_48:
    dw  0x800
    dw  512 + gdt, 0x9